package com.starter.canal.other;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.stream.Collectors;

/**
 * 类的描述
 *
 * @author Administrator
 * @date 2022-08-23
 */
public class MethodTest {
    public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
        A a1 = new A();
        Class clazz = a1.getClass();
        Method[] declaredMethods = clazz.getDeclaredMethods();
        System.out.println("declaredMethods=" + Arrays.stream(declaredMethods).map(item -> item.getName() + "()").collect(Collectors.toList()));
        Method[] methods = clazz.getMethods();
        System.out.println("methods=" + Arrays.stream(methods).map(item -> item.getName() + "()").collect(Collectors.toList()));

        // 注：如果方法没有返回值，则 method.invoke() 返回 null，否则返回具体的值
        System.out.println("=================== 调用 m1() 方法");
        Method m11 = clazz.getMethod("m1", new Class[]{});
        Method m12 = clazz.getMethod("m1");
        // 反射调用，等价于 a1.m1()
        Object result11 = m11.invoke(a1, new Object[]{});
        Object result12 = m12.invoke(a1);
        System.out.println("反射调用m1()结果：result11=" + result11 + "，result12=" + result12);

        // 获取 m2() 方法：名称和参数列表来决定 getMethod获取的是public的方法 getDelcaredMethod自己声明的方法
        System.out.println("==================调用 m2(int a, int b) 方法");
        Method m21 = clazz.getMethod("m2", new Class[]{int.class, int.class});
        Method m22 = clazz.getMethod("m2", int.class, int.class);
        // 反射调用，等价于 a1.m2(10, 20)
        Object result21 = m21.invoke(a1, new Object[]{10, 20});
        Object result22 = m22.invoke(a1, 10, 20);
        System.out.println("反射调用m2()结果：result21=" + result21 + "，result22=" + result22);

        System.out.println("==================调用 m3(String a, String b) 方法");
        Method m31 = clazz.getMethod("m3", new Class[]{String.class, String.class});
        Method m32 = clazz.getMethod("m3", String.class, String.class);
        // 反射调用，等价于 a1.m3("hello", "WORLD")
        Object result31 = m31.invoke(a1, new String[]{"hello", "WORLD"});
        Object result32 = m32.invoke(a1, "hello", "WORLD");
        System.out.println("反射调用m3()结果：result31=" + result31 + "，result32=" + result32);
    }
}

class A {
    public void m1() {
        System.out.println("hello world");
    }

    public int m2(int a, int b) {
        int result = a + b;
        System.out.println(result);
        return result;
    }

    public void m3(String a, String b) {
        System.out.println(a.toUpperCase() + ", " + b.toLowerCase());
    }
}
